# encoding: utf-8
""" 
@author:Daniel 
@license: Apache Licence 
@file: api_base_builder.py 
@time: 2020/07/16
@contact: tongdangdang1@yy.com
"""

from .better_abc import ABCMeta, abstract_attribute
from functools import wraps


def field(field_type):
    def field_decorator(func):
        field_name = func.__name__
        func.__is_field__ = True

        @wraps(func)
        def wrapper(self, field_value):
            if field_type == 'boolean' or field_type == 'Boolean':
                field_value = str(field_value).lower()
            self.field_dict.setdefault((field_name, field_type, field_value))
            return func(self, field_value)

        return wrapper

    return field_decorator


class FiledBaseBuilder(metaclass=ABCMeta):
    """ Api Base builder class for build field rpc command

    """
    @abstract_attribute
    def api_name(self):
        pass

    def __init__(self):
        self.field_dict = {}
        self.field_cmd = {}

    def build(self):
        field_names = {
            name
            for name in dir(self)
            if getattr(getattr(self, name), '__is_field__', False)
        }
        
        if not self.field_dict:
            raise Exception('Pleae set field')

        param = list(zip(*self.field_dict))

        # {field:yy.com.thunderbolt.config.DemoConfig, param_name:[mUid, mChannelId], param_type:[String, String], param_value:[234,567]},
        self.field_cmd.setdefault("field", self.api_name)
        self.field_cmd.setdefault("param_name", list(param[0]))
        self.field_cmd.setdefault("param_type", list(param[1]))
        self.field_cmd.setdefault("param_value", list(param[2]))
        return str(self.field_cmd)

    def methods(self):
        return (list(filter(lambda m: not m.startswith("__") and not m.endswith("__") and callable(getattr(self, m)),
                            dir(self))))


class DemoConfigBuilder(FiledBaseBuilder):
    api_name = "yy.com.thunderbolt.config.DemoConfig"

    @field("int")
    def uid(self, uid):
        return self

    @field("string")
    def mode(self, mode):
        return self


if __name__ == "__main__":
    api = DemoConfigBuilder().uid(1).mode("free").build()
    # api = DemoConfigBuilder().build()
    print(api)
